/* -------------------------------------------------------------------------
 *
 * pg_subscription.h
 *	  "订阅" 系统目录 (pg_subscription) 的定义
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/catalog/pg_subscription.h
 *
 * NOTES
 *	  Catalog.pm 模块读取此文件并推导模式信息。
 *
 * -------------------------------------------------------------------------
 */
#ifndef PG_SUBSCRIPTION_H
#define PG_SUBSCRIPTION_H

#include "access/xlogdefs.h"
#include "catalog/genbki.h"
#include "catalog/pg_subscription_d.h"

#include "nodes/pg_list.h"

/*
 * 两阶段三值状态。有关这些状态的更多信息，请参见 worker.c 顶部的评论。
 */
#define LOGICALREP_TWOPHASE_STATE_DISABLED 'd'
#define LOGICALREP_TWOPHASE_STATE_PENDING 'p'
#define LOGICALREP_TWOPHASE_STATE_ENABLED 'e'

/* ----------------
 *		pg_subscription 定义。cpp 将其转换为
 *		typedef struct FormData_pg_subscription
 * ----------------
 */

/*
 * 从技术上讲，订阅位于数据库内部，因此共享目录似乎很奇怪，但复制启动进程需要访问所有
 * 订阅以能够启动工作进程，因此我们必须将它们放在共享的、固定的目录中。
 *
 * 注意：system_views.sql 中有一个 GRANT，用于授予公共选择
 * 所有列的访问权限，除了 subconninfo。添加新列时，
 * 一定要更新该信息（或者，如果新列不应公开可读，更新相关的注释和 catalogs.sgml）。
 */
CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(6101,SubscriptionRelation_Rowtype_Id) BKI_SCHEMA_MACRO
{
	Oid			oid;			/* oid */

	Oid			subdbid BKI_LOOKUP(pg_database);	/* 订阅所在的数据库 */

	XLogRecPtr	subskiplsn;		/* 在此 LSN 完成的所有更改都将被跳过 */

	NameData	subname;		/* 订阅的名称 */

	Oid			subowner BKI_LOOKUP(pg_authid); /* 订阅的拥有者 */

	bool		subenabled;		/* 如果订阅已启用（工作进程应在运行），则为真 */

	bool		subbinary;		/* 如果订阅希望发布者以二进制格式发送数据，则为真 */

	bool		substream;		/* 流处理进行中的事务。 */

	char		subtwophasestate;	/* 流处理两阶段事务 */

	bool		subdisableonerr;	/* 如果工作进程错误应导致订阅被禁用，则为真 */

#ifdef CATALOG_VARLEN			/* 可变长度字段从这里开始 */
	/* 连接字符串到发布者 */
	text		subconninfo BKI_FORCE_NOT_NULL;

	/* 发布者上的槽名称 */
	NameData	subslotname BKI_FORCE_NULL;

	/* 工作进程的同步提交设置 */
	text		subsynccommit BKI_FORCE_NOT_NULL;

	/* 订阅的出版物列表 */
	text		subpublications[1] BKI_FORCE_NOT_NULL;
#endif
} FormData_pg_subscription;

typedef FormData_pg_subscription *Form_pg_subscription;

DECLARE_TOAST_WITH_MACRO(pg_subscription, 4183, 4184, PgSubscriptionToastTable, PgSubscriptionToastIndex);

DECLARE_UNIQUE_INDEX_PKEY(pg_subscription_oid_index, 6114, SubscriptionObjectIndexId, on pg_subscription using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_subscription_subname_index, 6115, SubscriptionNameIndexId, on pg_subscription using btree(subdbid oid_ops, subname name_ops));

typedef struct Subscription
{
	Oid			oid;			/* 订阅的Oid */
	Oid			dbid;			/* 订阅所在数据库的Oid */
	XLogRecPtr	skiplsn;		/* 在此 LSN 完成的所有更改都将被跳过 */
	char	   *name;			/* 订阅的名称 */
	Oid			owner;			/* 订阅拥有者的Oid */
	bool		enabled;		/* 指示订阅是否已启用 */
	bool		binary;			/* 指示订阅是否希望以二进制格式获取数据 */
	bool		stream;			/* 允许流处理进行中的事务。 */
	char		twophasestate;	/* 允许流处理两阶段事务 */
	bool		disableonerr;	/* 指示如果发生工作进程错误，订阅是否应自动禁用 */
	char	   *conninfo;		/* 连接字符串到发布者 */
	char	   *slotname;		/* 复制槽的名称 */
	char	   *synccommit;		/* 工作进程的同步提交设置 */
	List	   *publications;	/* 要订阅的出版物名称列表 */
} Subscription;

extern Subscription *GetSubscription(Oid subid, bool missing_ok);
extern void FreeSubscription(Subscription *sub);
extern void DisableSubscription(Oid subid);
extern Oid	get_subscription_oid(const char *subname, bool missing_ok);
extern char *get_subscription_name(Oid subid, bool missing_ok);

extern int	CountDBSubscriptions(Oid dbid);

#endif							/* PG_SUBSCRIPTION_H */
